
package com.ce.pms.house.service.impl;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import org.hibernate.proxy.HibernateProxy;
import org.springframework.util.Assert;

import com.ce.pms.charge.model.AccountDomain;
import com.ce.pms.common.annotation.AssociatedBuildingQuery;
import com.ce.pms.common.model.SysInfo;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.common.util.StringAnalysiUtil;
import com.ce.pms.common.util.UpLoadFile;
import com.ce.pms.customer.model.ProRightDO;
import com.ce.pms.customer.vo.CustomerHouseVO;
import com.ce.pms.exception.BusinessException;
import com.ce.pms.house.model.BuildingDomain;
import com.ce.pms.house.model.ChargePrecinctDomain;
import com.ce.pms.house.model.CoalitionHouseDomain;
import com.ce.pms.house.model.FlatDomain;
import com.ce.pms.house.model.HouseDomain;
import com.ce.pms.house.model.HouseGrp;
import com.ce.pms.house.model.HousePlan;
import com.ce.pms.house.model.HouseType;
import com.ce.pms.house.model.ImageDomain;
import com.ce.pms.house.model.MeterDomain;
import com.ce.pms.house.model.ProjectDomain;
import com.ce.pms.house.service.IHouseService;
import com.ce.pms.house.vo.FlatVO;
import com.ce.pms.house.vo.FloorVO;
import com.ce.pms.house.vo.HouseIconVO;
import com.ce.pms.house.vo.HouseSearchVO;
import com.ce.pms.house.vo.HouseStatusVO;
import com.ce.pms.house.vo.HouseTypeVO;
import com.ce.pms.house.vo.HouseVO;
import com.ce.pms.house.vo.ImageVO;
import com.ce.pms.house.vo.PrecinctVO;
import com.ce.util.BeanUtil;
import com.ce.util.BlankUtil;
import com.sitechasia.webx.core.support.Page;
/**
 *
 * 功能描述: pms2#com.ce.pms.house.service.impl.HouseServiceImpl <br>
 *
 *
 * @author  付湘辉  <br>
 * Created on： 2008-7-22 <br>
 * @author <br>
 * update on： <br>
 * why: <br>
 */
public class HouseServiceImpl extends ProductServiceImpl implements IHouseService {

	/**
	 *
	 * 功能描述: 添加一个房屋信息(住宅)
	 *
	 * @author 付湘辉
	 * Created on:2008-7-1
	 *
	 * 修改原因：
	 * @param flatvo
	 * @return FlatVO 返回结果
	 */
	public FlatVO addHouse(FlatVO flatvo){

		try{
			super.checkParameterIsNull(flatvo,"common:parameters_null_exception, ");
			super.checkCreatorInfo(flatvo.getCreator());

			this.checkHouseNumberIsOnly(flatvo);

			//设置管理房标志为0
			flatvo.setIsVirtual(SysrefcodeDO.CONSTANTS_DIGITAL_ZERO);
			FlatDomain flatDomain = this.assembleV2D(flatvo);
			this.houseDao.saveObject(flatDomain);

			flatvo.setKeyword(flatDomain.getKeyword());
            flatvo.setSysdate(flatDomain.getSysInfo().getSysDate());
		} catch(BusinessException be){
			this.processIfProduceException(flatvo);
			throw be;
		} catch (Exception e){
			this.processIfProduceException(flatvo);
			super.logger.error(e.getMessage(), e);
			throw new BusinessException("house:house_save_exception",BusinessException.FAILURE);
		}

		return flatvo;
	}

	/**
	 * 功能描述: 检查指定房号的房间是否是单独的产权房间 <br>
	 * @param houseNumber
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-21  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean checkHouseIsLonely(String houseNumber){
		super.checkParameterIsNull(houseNumber, "common:parameters_null_exception, ");
		HouseDomain house = this.getHouseByNumber(houseNumber);
		if (BlankUtil.isBlank(house)) {
			throw new BusinessException("house:house_not_exist_exception",BusinessException.WARNING);
		}

		return this.getCoalition(house.getKeyword())==null;
	}

    /**
	 * 功能描述: 检查指定的房屋是否可以修改其状态。
	 * <ul><li>只有自住，空置，出租这三种状的房屋才能修改状态。</li></ul>
	 * @param houseId
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-29  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean checkHouseStatusCanbeModified(Long houseId){
		super.checkParameterIsNull(houseId, "common:parameters_null_exception, ");
		HouseDomain house = this.houseDao.findById(houseId);
		SysrefcodeDO status = house.getStatus();
		return this.isVSR(status.getValue());
	}

	/**
	 * 功能描述: 检查指定的房间是否在同一个楼栋中。
	 * houseIdString是一个房间id的拼接字符串，
     * 使用SQL语句查询这些房间所在的楼栋的数量，如果数量不为1,则返回false <br>
	 * @param houseIdString
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-31  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean checkHouseWhetherWithinSameBuilding(String houseIdString){
		super.checkParameterIsNull(houseIdString, "common:parameters_null_exception, ");
		if (!Pattern.matches(SysrefcodeDO.REGEX_ID_JOIN_STRING, houseIdString)) {
			throw new BusinessException("common:id_join_string_format_exception",BusinessException.WARNING);
		}
		Integer res = this.houseDao.getBuildingCountBy(houseIdString);
		return SysrefcodeDO.CONSTANTS_ONE == res;
	}

	/**
     * 功能描述: 对房号的唯一性进行检查，这种检查同时包括产权房和管理房。规则如下：
     * <ol>
     * <li>在同一建设期下不允许有相同的房屋号码。</li>
     * <li>参数projectId和houseId分别代表期数id和房屋id，它们可能为空值。</li>
     * <li>如果houseId不为空，一般用于验证修改房屋时查找不是这个id的房屋是否存在相同的房号houseNumber。</li>
     * </ol>
     *
     * @param projectId   建设期id
     * @param houseId   房屋id
     * @param houseNumber  房屋号码
     * @return boolean true:存在 false:不存在
     * @author：付湘辉
     *         <ul>
     *         <li>Create on:2008-7-2 </li>
     *         </ul>
     * @author：
     *          <ul>
     *          <li>Edit on: </li>
     *          <li>Why: </li>
     *          </ul>
     */
	public boolean checkIsOnlyHouseNoInHouseAndCoalitionHouse(Long projectId,Long houseId,String houseNumber){

		super.checkParameterIsNull(houseNumber, "house:house_number_null_exception");

		boolean result = this.houseDao.checkIsOnlyNumber(projectId,houseId,houseNumber);
		if (!result) {
			if (!BlankUtil.isBlank(houseId)) {
				result = this.coalitionHouseDao.checkUnitedHouseNumberExist(houseNumber,houseId);
			}else{
				result = this.coalitionHouseDao.checkUnitedHouseNumberExist(projectId,houseNumber);
			}
		}

		return result;
	}

	/**
	 *
	 * 功能描述: 检查同一个楼盘期数下的指定的房号在产权房和管理房中是否都不存在
	 *
	 * @author 付湘辉
	 * Created on:2008-7-1
	 *
	 * 修改原因：
	 *
	 * @param projectId
	 * @param houseNumber
	 *
	 * @return boolean 返回结果
	 */
	public boolean checkIsOnlyHouseNoInHouseAndCoalitionHouse(Long projectId,String houseNumber){
		return this.checkIsOnlyHouseNoInHouseAndCoalitionHouse(projectId, null, houseNumber);
	}

	/**
	 *
	 * 功能描述: 检查指定的房号在产权房和管理房中是否都不存在
	 *
	 * @author 付湘辉
	 * Created on:2008-7-1
	 *
	 * 修改原因：
	 * @param houseNumber
	 * @return boolean 返回结果
	 */
	public boolean checkIsOnlyHouseNoInHouseAndCoalitionHouse(String houseNumber){
		return this.checkIsOnlyHouseNoInHouseAndCoalitionHouse(null, null, houseNumber);
	}

	public boolean checkIsOnlyHouseNoInHouseAndCoalitionHouse(String houseNumber , Long houseId){
		return this.checkIsOnlyHouseNoInHouseAndCoalitionHouse(null, houseId, houseNumber);
	}

    /**
	 * 功能描述: 删除一个房间， imageList是一个从调用方传入的列表，它必须是已初始化的，<br>
	 * 当这个房间有图片时，将放入这个列表，由调用者删除图片文件<br>
	 * @param houseId
	 * @param imageList
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-21  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public void deleteHouse(Long houseId,List<ImageVO> imageList){
		try{
			super.checkParameterIsNull("common:parameters_null_exception, ", houseId,imageList);
			FlatDomain flat = (FlatDomain) this.flatDao.findById(houseId);

            this.checkHouseDeleteRole(flat);

			ImageDomain lchnography =  flat.getIchnography();
			if (!BlankUtil.isBlank(lchnography)) {
				ImageVO tempImageVo = new ImageVO();
				tempImageVo.setPath(lchnography.getPath());
				tempImageVo.setName(lchnography.getName());
				imageList.add(tempImageVo);
			}

			ImageDomain pipelineImage = flat.getPipelineImage();
			if (!BlankUtil.isBlank(pipelineImage)) {
				ImageVO tempImageVo = new ImageVO();
				tempImageVo.setPath(pipelineImage.getPath());
				tempImageVo.setName(pipelineImage.getName());
				imageList.add(tempImageVo);
			}

			this.houseDao.deleteObject(flat);

		} catch(BusinessException be){
			throw be;
		} catch(Exception e){
			super.logger.error(e.getMessage(), e);
			throw new BusinessException("house:house_delete_failure_exception",BusinessException.FAILURE);
		}

	}

	/**
	 *
	 * 功能描述: 修改一个房屋信息(住宅)
	 *
	 * @author 付湘辉
	 * Created on:2008-7-1
	 *
	 * 修改原因：
	 * @param flatvo
	 * @return FlatVO 返回结果
	 */
	public FlatVO editHouse(FlatVO flatvo){

		try{
			super.checkParameterIsNull(flatvo, "common:parameters_null_exception, ");
			super.checkCreatorInfo(flatvo.getCreator());
			this.checkHouseNumberIsOnly(flatvo);

			FlatDomain flatDomain = this.assembleV2D(flatvo);
			this.houseDao.updateObject(flatDomain);

			flatvo.setModifier(flatvo.getCreator());
            flatvo.setModifierDate(flatDomain.getSysInfo().getModifyDate());

		} catch (BusinessException be){
			this.processIfProduceException(flatvo);
			throw be;
		} catch (Exception e){
			this.processIfProduceException(flatvo);
			super.logger.error(e.getMessage(), e);
			throw new BusinessException("house:house_edit_exception",BusinessException.FAILURE);
		}

		return flatvo;
	}

	/**
	    *
	    * 功能描述:  获取指定产权房id的管理房实体 <br>
	    *
	    * @param houseDomain
	    * @return
	    *
	    * Create author：付湘辉  <br>
	    * Create on:2008-7-25  <br>
	    * Edit author：  <br>
	    * Edit on:    <br>
	    * Why:     <br>
	    */
	   public CoalitionHouseDomain getCoalition(Long houseId){
		   super.checkParameterIsNull(houseId, "common:parameters_null_exception, ");
		   HouseDomain house = this.houseDao.findById(houseId);
		   return this.houseDao.getCoalition(house);
	   }


    /**
	 *
	 * 功能描述: 根据房屋id查询房屋信息，使用HouseVO对象封装内容,<br>
	 * 此方法返回的是一个住宅房的详细信息,如果调用要得到一个FlatVO，可以使用强制转换操作。
	 *
	 * @author 付湘辉
	 * Created on:2008-7-4
	 *
	 * 修改原因：
	 * @param houseId　房屋id
	 * @return HouseVO 返回结果
	 */
	public HouseVO getFlatHouseById(Long houseId){
		if (BlankUtil.isBlank(houseId)) {
			return null;
		}
		FlatVO resultFlat = null;

		HouseDomain house = this.flatDao.findById(houseId);
		if (BlankUtil.isBlank(house)) {
			return null;
		}

		resultFlat = this.assembleD2V((FlatDomain)house);

		return resultFlat;
	}

	/**
	 * 功能描述:查询指定的普通住宅<br>
	 * @param keyword
	 * @return<br>
	 * Create author:罗军林<br>
	 * Create on:2009-1-8<br>
	 * Edit author:<br>
	 * Edit on:<br>
	 * Why:<br>
	 */
	public FlatVO getFlatHouseVO(Long keyword){
		FlatDomain flat = flatDao.getFlatDomain(keyword);
		return assembleD2V(flat);
	}

	/**
	 * 根据房号找出房屋与业主信息
	 */
	public List<CustomerHouseVO> getHouseAndCustomerBy(String houseNumber) {
		super.checkParameterIsNull(houseNumber, "house:house_number_null_exception");

		List<Object[]> objs = this.houseDao.getHouseRCustomerInfo(houseNumber);
		if(BlankUtil.isBlank(objs)) {
			return null;
		}
		List<CustomerHouseVO> list = new ArrayList<CustomerHouseVO>();
		for(Object[] obj : objs)
		{
			CustomerHouseVO customerHouse = new CustomerHouseVO();
			customerHouse.setHouseId((Long)obj[0]);
			customerHouse.setHouseNumber((String)obj[1]);
			customerHouse.setOwnerName((String)obj[2]);
			list.add(customerHouse);
		}
		return list;
	}

	/**
	 * 功能描述:  <br>
	 * @param houseId
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2009-1-4  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public HouseDomain getHouseById(Long houseId) {
		return this.houseDao.loadById(houseId);
	}

   /**
	 *
	 * 功能描述: 根据期数和产权房号得到一个产权房实体
	 *
	 * @author 付湘辉
	 * Created on:2008-7-10
	 *
	 * 修改原因：
	 * @param houseNumber
	 * @return HouseDomain 返回结果
	 */
	public HouseDomain getHouseByNumber(Long projectId,String houseNumber) {
		super.checkParameterIsNull(houseNumber, "house:house_number_null_exception");
		return this.houseDao.getHouseDomainByHouseNumber(projectId,houseNumber);
	}

   /**
    *
    * 功能描述: 根据产权房号得到一个产权房实体
    *
    * @author 付湘辉
    * Created on:2008-7-10
    *
    * 修改原因：
    * @return HouseDomain 返回结果
    */
	public HouseDomain getHouseByNumber(String houseNumber) {
		return this.getHouseByNumber(houseNumber, false);
	}

	/**
	 * 功能描述: 根据产权房号得到一个产权房实体,
     * virtual是一个开关标志，为true则查询包括管理房 <br>
	 * @param houseNumber
	 * @param virtual 是否查询管理房　true：是　false：否
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-15  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public HouseDomain getHouseByNumber(String houseNumber,boolean virtual) {
		super.checkParameterIsNull(houseNumber, "house:house_number_null_exception");
		return this.houseDao.getHouseDomainByHouseNumber(houseNumber,virtual);
	}

	/**
	 * 功能描述: 根据房号得到这间房所在产权共有的管理房下所有产权房信息，包括它本身 <br>
	 * 1：调用房屋接口得到此房号对应的房屋信息 <br>
	 * 2：利用HouseDomain 实体关系得到基产权共有的管理房信息，没有则返回只包含它自己的列表 <br>
	 * 3：得到此管理房下的所有产权房屋信息 <br>
	 * @param houseNumber
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-9  <br>
	 * Edit author:   <br>
	 * Edit on:    <br>
	 * Why:    <br>
	 */
	public List<HouseDomain> getHouseDomainList(String houseNumber){
		super.checkParameterIsNull(houseNumber,"common:parameters_null_exception, ");

		//调用房屋接口得到此房号对应的房屋信息
		HouseDomain house = this.houseDao.getHouseDomainByHouseNumber(houseNumber);
        if (BlankUtil.isBlank(house)) {
            //系统中不存在此产权房
            throw new BusinessException("house:house_not_exist_exception",
            							BusinessException.WARNING);
        }

		List<HouseDomain> houseList = new ArrayList<HouseDomain>();

		//得到有效的产权共有类型的合并房实体
		CoalitionHouseDomain coalitionHouse =
				this.flatDao.getShareProRightCoalition(house);
		if (BlankUtil.isBlank(coalitionHouse)) {
			houseList.add(house);
			return houseList;
		}

		Set<HouseDomain> houseSet = coalitionHouse.getHouses();

		if (!BlankUtil.isBlank(houseSet)) {
			//得到此合并房下的所有产权房屋信息
			houseList.addAll(houseSet);
		}

		return houseList;
	}

	/**
	 *
	 * 功能描述: 查询所有户型列表
	 *
	 * @author 付湘辉
	 * Created on:2008-6-30
	 *
	 * 修改原因：
	 * @return List<HousePlan> 返回结果
	 */
	public List<HousePlan> getHouseModels(){
		return this.houseDao.getHouseModels();
	}

	/**
    *
    * 功能描述:  根据户型ID获取到房屋类型 <br>
    *
    * @param planId
    * @return HouseTypeVO
    *
    * Create author：李昊龙  <br>
    * Create on:2008-10-14  <br>
    * Edit author：  <br>
    * Edit on:    <br>
    * Why:     <br>
    */
	public HousePlan getHousePlanByPlanId(Long planId) {
		HousePlan plan = super.houseDao.getHousePlanById(planId);
		return plan;
	}

	/**
	 *
	 * 功能描述: 查询所有房间状态列表
	 *
	 * @author 付湘辉
	 * Created on:2008-6-30
	 *
	 * 修改原因：
	 * @return List<SysrefcodeDO> 返回结果
	 */
	public List<SysrefcodeDO> getHouseStatuses(){
		return super.sysrefcodeDao.querySysrefCodesByCode(SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_CODE);
	}

	/**
	 * 功能描述: 查询房间状态列表,根codeString有选择的查询状态 <br>
	 * @param codeString
	 * @return List<SysrefcodeDO>
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-25  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	@SuppressWarnings("unchecked")
	public List<SysrefcodeDO> getHouseStatuses(String codeString){
		if (!Pattern.matches(SysrefcodeDO.REGEX_VALUE_JOIN_STRING, codeString)) {
			throw new BusinessException("common:value_join_string_format_exception",BusinessException.WARNING);
		}
		return super.sysrefcodeDao.querySysrefCodesByCode(SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_CODE, codeString);
	}

	/**
    *
    * 功能描述:  根据户型ID获取到房屋类型 <br>
    *
    * @param planId
    * @return HouseTypeVO
    *
    * Create author：李昊龙  <br>
    * Create on:2008-10-14  <br>
    * Edit author：  <br>
    * Edit on:    <br>
    * Why:     <br>
    */
	@Deprecated
	public HouseTypeVO getHouseTypeByPlanId(Long planId) {
		HousePlan plan = super.houseDao.getHousePlanById(planId);
		HouseType houseType = super.houseDao.getHouseTypeById(plan.getType().getKeyword());

		HouseTypeVO houseTypeVO = new HouseTypeVO();
		houseTypeVO.setName(houseType.getName());
		houseTypeVO.setCode(houseType.getCode());

		return houseTypeVO;
	}

	/**
	 * Function: 根据房号找出其业主姓名,若有多个用,号隔开
	 * @param houseNumber
	 * @return
	 * Create author:燕大为
	 * Create on:2008-6-25
	 * Edit author:
	 * Edit on:
	 * Why:
	 */
	public String getOwnerNameBy(String houseNumber) {
		StringBuffer sb = new StringBuffer("");
		List<Object[]> objs = this.houseDao.getHouseRCustomerInfo(houseNumber);
		if(!BlankUtil.isBlank(objs))
		{
			for(Object[] obj : objs)
			{
				sb.append(obj[2]).append(",");
			}
			sb = sb.deleteCharAt(sb.length()-1);
		}
		return sb.toString();
	}

	/**
	 * 功能描述: 根据房屋id查找所属管理区，在得到的结果VO中只包括管理区ID和编号字段 <br>
	 * @param houseId 房屋id
	 * @param isVirtual 是否是管理房，可为空；1管理房，0产权房
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-9-17  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public PrecinctVO getPrecinctVOByHouseId(Long houseId,String isVirtual){
		Long buildingId=this.getBuildingIdByHouseId(houseId, isVirtual);
		//根据楼栋查询当前收费管理区
		ChargePrecinctDomain cpDomain = this.chargePrecinctDao.findChargePrecinctBy(buildingId);
		PrecinctVO precinctVO = new PrecinctVO();
		precinctVO.setKeyword(cpDomain.getKeyword());
		precinctVO.setPrecinctCode(cpDomain.getPrecinctCode());
		return precinctVO;
	}

	/**
	 * 功能描述: 修改房间状态 <br>
	 * @param houseId
	 * @param houseStatusId
	 * @return HouseVO
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-21  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public HouseVO modifyHouseStatus(Long houseId,Long houseStatusId){
		super.checkParameterIsNull("common:parameters_null_exception", houseId,houseStatusId);
		FlatDomain flatDo  = (FlatDomain)this.flatDao.findById(houseId);
		SysrefcodeDO houseStatus = flatDo.getStatus();

		if (!this.isVSR(houseStatus.getValue())) {
			throw new BusinessException("house:house_status_modify_exception",BusinessException.WARNING);
		}

		houseStatus = super.sysrefcodeDao.findById(houseStatusId);
		flatDo.setStatus(houseStatus);

		return this.assembleD2V(flatDo);
	}


	/**
	 * 功能描述: 通知完成房间装修,
	 * 调用notifyHouseRenovationOutAction后,如果房间状态未入住将房间状态改为自住.  <br>
	 * @param houseId
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2009-1-13  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean notifyFinishRenovation(Long houseId){
		Assert.notNull(houseId);
		this.notifyHouseRenovationOutAction(houseId);

		HouseDomain houseDo = this.houseDao.findById(houseId);
		if (SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_NOOCCUPATION.equals(houseDo.getStatus().getValue())) {
			SysrefcodeDO sincetheliving = super.sysrefcodeDao.getSysrefCodesByCode(
					SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_CODE,
					SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_SINCETHELIVING);
			houseDo.setStatus(sincetheliving);
			this.houseDao.updateObject(houseDo);
		}
		return true;
	}

	/**
	 * 功能描述: 通知修改房间装修状态为装修中  <br>
	 * @param houseId
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2009-1-13  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean notifyHouseRenovationInAction(Long houseId){
		Assert.notNull(houseId);
		SysrefcodeDO decoration = super.sysrefcodeDao.getSysrefCodesByCode(
				SysrefcodeDO.HM_HOUSE_HOUSE_SUB_STATUZ_CODE,
				SysrefcodeDO.HM_HOUSE_HOUSE_SUB_STATUZ_VALUE_DECORATION);
		HouseDomain houseDo = this.houseDao.findById(houseId);
		houseDo.setSubStatuz(decoration);
		this.houseDao.updateObject(houseDo);
		return true;
	}

	/**
	 * 功能描述: 通知修改房间装修状态为空  <br>
	 * @param houseId
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2009-1-13  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean notifyHouseRenovationOutAction(Long houseId){
		Assert.notNull(houseId);
		HouseDomain houseDo = this.houseDao.findById(houseId);
		houseDo.setSubStatuz(null);
		this.houseDao.updateObject(houseDo);
		return true;
	}

	/**
	 * 功能描述:入伙中物品移交,移交钥匙状态为"是"时调用
	 * 通知房间状态修改为:
	 * <ol>
	 * <li>如果房屋为毛坯房，房屋状态改为"未入住",HM_HOUSE_HOUSE_STATUS = 002</li>
	 * <li>如果房屋为精装修，房屋状态改为"自住", HM_HOUSE_HOUSE_STATUS = 004</li>
	 * </ol>
	 * @param houseIds
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2009-1-13  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean notifyHouseStateFinishOccupation(List<Long> houseIds){
		Assert.isTrue(!BlankUtil.isBlank(houseIds));
		List<FlatDomain> list = this.flatDao.queryFlatDomainListByIds(StringAnalysiUtil.portfolioFormattedString(houseIds));

		for (FlatDomain domain : list) {
			if (SysrefcodeDO.CS_FLAT_DELIVERY_STANDARD_VALUE_ROUGH.equals(domain.getDeliveryLimitation().getValue())) {
				SysrefcodeDO nooccupation = super.sysrefcodeDao.getSysrefCodesByCode(
						SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_CODE,
						SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_NOOCCUPATION);
				domain.setStatus(nooccupation);
			}else if(SysrefcodeDO.CS_FLAT_DELIVERY_STANDARD_VALUE_HARDCOVER.equals(domain.getDeliveryLimitation().getValue())){
				SysrefcodeDO sincetheliving = super.sysrefcodeDao.getSysrefCodesByCode(
						SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_CODE,
						SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_SINCETHELIVING);
				domain.setStatus(sincetheliving);
			}
			this.flatDao.updateObject(domain);
		}
		return true;
	}

	/**
	 * 功能描述:	通知将房间状态修改为入伙中,HM_HOUSE_HOUSE_STATUS = 003
     * 入伙中物品移交,移交钥匙状态为"否"时调用.<br>
	 * @param houseIds 待修改的产权房id列表
	 * @return Boolean
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2009-1-13  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean notifyHouseStateOccupationInAction(List<Long> houseIds){
		Assert.isTrue(!BlankUtil.isBlank(houseIds));
		List<HouseDomain> list = this.houseDao.queryHouseDomainListByIds(StringAnalysiUtil.portfolioFormattedString(houseIds));
		SysrefcodeDO status = super.sysrefcodeDao.getSysrefCodesByCode(
				SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_CODE,
				SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_INTHEOCCUPATION);
		for (HouseDomain domain : list) {
			domain.setStatus(status);
			this.houseDao.updateObject(domain);
		}
		return true;
	}

	/**
	 * 功能描述:通过一个房间ID，查询一个房间ID列表，如果这个指定的房间是管理房，
	 * 得到它的产权房ID列表，如果它是产权房，同时又在一个管理房下，则也查出所有相关的产权房ID和它本身，
	 * 当它是一个独立的产权房时，在返回的列表只包含它本身  <br>
	 * @param houseId 房间ID
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-12-24  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public List<Long> queryAllHouseIdListById(Long houseId){
		Assert.notNull(houseId);
		HouseDomain house = this.houseDao.findById(houseId);
		List<Long> tempList = new ArrayList<Long>();
		//如果是管理房，找到它所有的产权房
		if (SysrefcodeDO.CONSTANTS_DIGITAL_ONE.equals(house.getIsVirtual())) {
			CoalitionHouseDomain cHouse = this.coalitionHouseDao.findById(houseId);
			Set<HouseDomain>set = cHouse.getHouses();
			for (HouseDomain domain : set) {
				tempList.add(domain.getKeyword());
			}
		}else{
			CoalitionHouseDomain cHouse = this.getCoalition(houseId);
			if (!BlankUtil.isBlank(cHouse)) {
				Set<HouseDomain>set = cHouse.getHouses();
				for (HouseDomain domain : set) {
					tempList.add(domain.getKeyword());
				}
			}else{
				tempList.add(houseId);
			}
		}
		return tempList;
	}

	/**
	 *
	 * 功能描述: 根据楼栋id查询在这个楼栋下的不同状态的房间的数量VO列表，全部用"000"表示
	 *
	 * @author 付湘辉
	 * Created on:2008-7-3
	 *
	 * 修改原因：
	 * @param buildingId
	 * @return List<HouseStatusVO> 返回结果
	 */
	public List<HouseStatusVO> queryDifferentStatusHouseStatusListBybuildingId(Long buildingId){
		List<HouseStatusVO> statusVoList = new ArrayList<HouseStatusVO>();
		if (BlankUtil.isBlank(buildingId)) {
			return statusVoList;
		}

		List tempList = null;
		HouseStatusVO houseStatusVO = null;
		Integer totalCounts = 0;
		int i = 0;//用于循环作用

		//查询在这个楼栋下的不同状态的房间的数量VO列表
		tempList = this.houseDao.queryDifferentStatusHouseCountBybuildingId(buildingId);
		int size = tempList.size();

		for (; i < size; i++) {
			Object[] obj = (Object[])tempList.get(i);
			houseStatusVO = this.assembleHouseStatusVO(obj);
			statusVoList.add(i, houseStatusVO);

			totalCounts+=houseStatusVO.getStatusCount();//累和全部数量
		}

		//全部状态的总和
		houseStatusVO
			= this.assembleHouseStatusVO(SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_ALL,
								         SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_NAME_ALL,
								         totalCounts);
		statusVoList.add(i, houseStatusVO);

		return statusVoList;
	}

	/**
	 *
	 * 功能描述: 根据房屋搜索VO条件，查询楼栋下房屋列表分页信息<br>
	 * 此方法返回一个<b>Map<Integer, Object></b> <br>
	 * 里面第一个键值对是整个楼栋里房间最多的楼层的房间数量,用Integer存储 <br>
	 * 第二个键值对是楼栋下房屋分页列表信息，用List<FloorVO>存储 <br>
	 * 第三个键值对是楼栋下房间总数,用Integer存储<br>
	 *
	 * @author 付湘辉 <br>
	 * Created on:2008-7-2 <br>
	 *
	 * 修改原因： <br>
	 * @param searchVO <br>
	 * @param currentPage <br>
	 * @param pageSize <br>
	 * @return Map<Integer, Object> <br>
	 */
	@AssociatedBuildingQuery(alias="HHN",property4Building="BUILDING_ID",beginStr=" AND ",endStr=" ",insertAfterPoint="WHERE 1=1")
	public Map<Integer, Object> queryHouseIconListByPage(HouseSearchVO searchVO,Integer currentPage,Integer pageSize){
		super.checkParameterIsNull(searchVO,"common:parameters_null_exception, ");
		super.checkParameterIsNull(searchVO.getBuildingId(),"common:parameters_null_exception, ");

		Map<Integer, Object> map = new HashMap<Integer, Object>();
		List<Object[]> tempList = null;
		List<FloorVO> list = new ArrayList<FloorVO>();
		List<HouseIconVO> iconList = null;
		HouseIconVO tempHouseIconVo = null;
		Integer tmpMaxHouseCount = 0;
		FloorVO floorVO = null;
		//默认的每层房间数，当某层房间数小于此值时，补足此数
		final int HOUSECOUNT = 5;

		//查询楼栋下房屋图示列表信息,在返回的list中是Object[]
		tempList = this.houseDao.queryHouseIconList(searchVO);

		int totalFloorSize = 0;

		int forCount = 0;//计算总记录数

		if (!BlankUtil.isBlank(tempList)) {

			totalFloorSize = tempList.size();

			int previousFloors = 0;
			for (int i = 0; i < totalFloorSize; i++) {
				Object[] obj = tempList.get(i);
				floorVO = new FloorVO();

				int cusFloor = ((Short)obj[1]).intValue();//取本次层数
				if (cusFloor == previousFloors) {
					continue;
				}

				previousFloors = cusFloor;//前一次取的层数

				floorVO.setFloor(cusFloor);//楼层
				iconList = floorVO.getHouseIconList();//得到房屋图示VO列表

				int tempHouseCount = 0;//用于统计同一层房间数量

				//
				for (int j = 0; j < totalFloorSize; j++) {
					Object[] obj2 = tempList.get(j);
					int floor2 = ((Short)obj2[1]).intValue();

					if (floor2 == cusFloor) {
						tempHouseIconVo = this.assemblevObjArray2V(obj2);
						iconList.add(tempHouseCount++, tempHouseIconVo);
					}
				}

				//得到整个楼栋里房间最多的楼层的房间数量
				if (tmpMaxHouseCount < tempHouseCount) {
					tmpMaxHouseCount=tempHouseCount;
				}

				list.add(forCount++, floorVO);//添加记录
			}
		}
		tmpMaxHouseCount = tmpMaxHouseCount<HOUSECOUNT?HOUSECOUNT:tmpMaxHouseCount;//取得最大房间数
		List<FloorVO> resultList = this.paginationList(currentPage, pageSize, list);//得到分页数据

		//处理房间数不够最大数量的情况　　
		this.processInsufficientNumber(tmpMaxHouseCount, resultList);

		map.put(0, tmpMaxHouseCount);
		map.put(1, resultList);
		map.put(2, Integer.valueOf(forCount));//记录总数，这里用 list.size() 也可以

		return map;
	}

	/**
	 * 功能描述:通过一个房间ID，查询一个房间ID列表，如果这个指定的房间是管理房，
	 * 得到它的产权房ID列表，否则返回的列表中只有它本身的ID  <br>
	 * @param houseId 一个拥用有效账户的房间ID
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-12-24  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public List<Long> queryHouseIdListById(Long houseId){
		Assert.notNull(houseId);
		HouseDomain house = this.houseDao.findById(houseId);
		List<Long> tempList = new ArrayList<Long>();
		//如果是管理房，找到它所有的产权房
		if (SysrefcodeDO.CONSTANTS_DIGITAL_ONE.equals(house.getIsVirtual())) {
			CoalitionHouseDomain cHouse = this.coalitionHouseDao.findById(houseId);
			Set<HouseDomain>set = cHouse.getHouses();
			for (HouseDomain domain : set) {
				tempList.add(domain.getKeyword());
			}
		}else{
			tempList.add(houseId);
		}
		return tempList;
	}
	
	/**
	 *
	 * 功能描述: 根据房屋搜索VO条件，查询指定楼栋和单元下房屋列表信息
	 * @author 付湘辉
	 * Created on:2008-7-2
	 *
	 * 修改原因：
	 * @param searchVO
	 * @return List<FlatVO> 返回结果
	 */
	public List<FlatVO> queryHouseListBy(HouseSearchVO searchVO){

		List<FlatVO> list = new ArrayList<FlatVO>();
		FlatVO tempFlatVo = null;
		List<Object[]> tempList = null;

		tempList = this.houseDao.queryHouseIconList(searchVO);

		int totalFloorSize = 0;
		if (!BlankUtil.isBlank(tempList)) {

			totalFloorSize = tempList.size();
			for (int i = 0; i < totalFloorSize; i++) {
				Object[] obj = tempList.get(i);
				tempFlatVo = new FlatVO();

				tempFlatVo.setKeyword(((BigInteger)obj[0]).longValue());//房屋产品id
				int cusFloor = ((Short)obj[1]).intValue();//取层数
				tempFlatVo.setFloor(cusFloor);//楼层
				tempFlatVo.setHouseNumber(obj[4]==null?"":(String)obj[4]);//产权房号
				tempFlatVo.setStatusValue(obj[5]==null?"":(String)obj[5]);//房屋状态

				list.add(i, tempFlatVo);//添加记录
			}
		}

		return list;
	}

	/**
    *
    * 功能描述: 根据房屋搜索VO条件，查询楼栋下房屋列表分页信息。 <br>
    * <ul>
    * <li>此方法调用{@link com.ce.pms.house.dao.impl.HouseDaoImpl#queryPagedHouses(HouseSearchVO, Integer, Integer)}方法，
    *  在得到的Page结果中是Object[]列表，为便于Action使用，使用FlatVO重新封装</li>
    * </ul>
    *
    * @param searchVO
    * @param currentPage
    * @param pageSize
    * @return Page
    *
    * Create author:付湘辉  <br>
    * Create on:2008-7-2  <br>
    * Edit author:  <br>
    * Edit on:    <br>
    * Why:     <br>
     */

	public Page queryHouseListByPage(HouseSearchVO searchVO,Integer currentPage,Integer pageSize){

		super.checkParameterIsNull(searchVO, "common:parameters_null_exception, ");

		List<FlatVO> list = new ArrayList<FlatVO>();
		FlatVO flatvo = null;
		//得到房间分页列表信息
		Page page= this.houseDao.queryPagedHouses(searchVO, currentPage, pageSize);

		int totalFloorSize = 0;
		if (!BlankUtil.isBlank(page.getResult())) {
			List tempList = page.getResult();
			totalFloorSize = tempList.size();
			for (int i = 0; i < totalFloorSize; i++) {
				Object[] obj = (Object[])tempList.get(i);
				flatvo = this.assemblevObjArray2FlatVO(obj);
				list.add(i, flatvo);
			}

            page.setResult(list);
		}

        return page;
	}

	/**
	 * 功能描述: 查找指定产权房的下一间产权房，以所在楼栋，单元(如果有)，楼层，房号为排序规则 <br>
	 * @param houseId
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-10-17  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public HouseVO queryNextHouseById(Long houseId){
		super.checkParameterIsNull(houseId, "common:parameters_null_exception,ID");

		List<Object[]> list = this.houseDao.queryALLHouseSorted();
		try {
			for (Object[] objects : list) {
				HouseVO tempVo = this.assembleHouseVO(objects);
				if (houseId.equals(tempVo.getKeyword())) {
					int index = list.indexOf(objects);
					return this.assembleHouseVO(list.get(++index));
				}
			}
		} catch (IndexOutOfBoundsException e) {

		}

		return null;
	}

	/**
	 * 功能描述:  保存平面图和管线图<br>
	 * @param flatVO
	 * @param flatDomain
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-1  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private void addOrEditIchnoAndPipeImage(FlatVO flatVO, FlatDomain flatDomain) {
		// 平面图
		flatDomain.setIchnography(super.imageService.getPossibleImageDomain(
				flatVO.getIchnographyVo(), flatVO.getCreator()));

		// 管线图
		flatDomain.setPipelineImage(super.imageService.getPossibleImageDomain(
				flatVO.getPipelineVo(), flatVO.getCreator()));
	}
	
	/**
	 * 功能描述: 用FlatDomain对象装配一个FlatVO对象
	 *
	 * @author 付湘辉
	 * Created on:2008-7-7
	 *
	 * 修改原因：
	 *
	 * @param flatVO
	 * @param flatDO
	 * @return FlatVO 返回结果
	 */
	private FlatVO assembleD2V(FlatDomain flatDO) {
		FlatVO flatVO = null;
		if (!BlankUtil.isBlank(flatDO)) {
			flatVO = new FlatVO();

			BeanUtil.convertVoAsDo(flatDO, flatVO);
//			PopulateUtil.populate(flatDO, flatVO);

			BuildingDomain building = flatDO.getBuilding();//得到所在楼栋信息
			if (!BlankUtil.isBlank(building)) {
				flatVO.setBuildingId(building.getKeyword());//楼栋id
				flatVO.setBuildingName(building.getName());//楼栋名称

				ProjectDomain projectDomain = building.getProject();//得到建设期数信息
				if (!BlankUtil.isBlank(projectDomain)) {
					flatVO.setProjectId(projectDomain.getKeyword());//建设期id
					flatVO.setProjectName(projectDomain.getName());//建设期名称
				}
			}

			CoalitionHouseDomain coalitionHouse = this.flatDao.getCoalition(flatDO);
			if (!BlankUtil.isBlank(coalitionHouse)) {
				flatVO.setCoalitionHouseId(coalitionHouse.getKeyword());//管理房id
				flatVO.setCoalitionNumber(coalitionHouse.getHouseNumber());//管理房号码
			}

			HouseGrp houseGrp = flatDO.getHouseGrp();//得到所在楼栋单元信息
			if (!BlankUtil.isBlank(houseGrp)) {
				flatVO.setHouseGrpid(houseGrp.getKeyword());//楼栋单元id
				flatVO.setHouseGrpName(houseGrp.getName());//楼栋单元名称
			}

			HousePlan housePlan = flatDO.getHousePlan();//得到住宅房屋户型信息
			if (!BlankUtil.isBlank(housePlan)) {
				flatVO.setHousePlanId(housePlan.getKeyword());//住宅房屋户型id
				flatVO.setHousePlanName(housePlan.getName());//住宅房屋户型名称
			}

			SysrefcodeDO deliveryLimitation = flatDO.getDeliveryLimitation();//得到房屋交房标准信息
			if (!BlankUtil.isBlank(deliveryLimitation)) {
				flatVO.setDeliveryLimitationId(deliveryLimitation.getId());//住宅房屋户型id
				flatVO.setDeliveryLimitationName(deliveryLimitation.getName());//住宅房屋户型名称
			}

			SysrefcodeDO status = flatDO.getStatus();//得到房屋状态信息
			if (!BlankUtil.isBlank(status)) {
				flatVO.setStatusId(status.getId());//住宅房屋状态id
				flatVO.setStatusValue(status.getValue());//住宅房屋状态value
				flatVO.setStatusName(status.getName());//住宅房屋状态名称
			}

			SysInfo sysInfo = flatDO.getSysInfo();//得到创建信息和修改信息
			if (!BlankUtil.isBlank(sysInfo)) {
				flatVO.setCreator(sysInfo.getCreator());//创建人id
				flatVO.setSysdate(sysInfo.getSysDate());//创建日期
				flatVO.setModifier(sysInfo.getModifier());//修改人id
				flatVO.setModifierDate(sysInfo.getModifyDate());//修改日期
			}

			//处理房屋朝向
			//房屋朝向存储以系统参数表中id的拼接字符串表示，形如：1,2,3 或　1,2,3,
			String directionIdStr = flatDO.getDirection();
			this.processDirection(flatVO, directionIdStr);

			this.getFlatImages(flatVO, flatDO);

            //设置是否登记了业主或其他住户信息标志
            flatVO.setHasCustomer(this.whetherRegistered(flatDO.getKeyword()));
		}

		return flatVO;
	}

	/**
	 * 功能描述:  装配一个图片VO<br>
	 * @param id
	 * @param name
	 * @param path
	 * @param operator
	 * @return ImageVO
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-15  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private ImageVO assembleD2V(Long id,String name,String path,Long operator){
		ImageVO tempImage = new ImageVO();
		tempImage.setId(id);
		tempImage.setName(name);
		tempImage.setPath(path);
		tempImage.setCreator(operator);
		return tempImage;
	}

   /**
 * 功能描述: 装配一个HouseStatusVO
 *
 * @author 付湘辉
 * Created on：2008-6-20
 *
 * @author
 * Update on：
 * 修改原因：
 *
 * @param statusVoDatas
 * @return
 */
private HouseStatusVO assembleHouseStatusVO(Object[] statusVoDatas) {
	return this.assembleHouseStatusVO(statusVoDatas[0].toString(),
									  statusVoDatas[1].toString(),
									  ((BigInteger) statusVoDatas[2]).intValue());
}

	/**
	 * 功能描述: 装配一个HouseStatusVO
	 *
	 * @author 付湘辉
	 * Created on:2008-7-7
	 *
	 * 修改原因：
	 * @param statusCode
	 * @param statusName
	 * @param temCount
	 * @return HouseStatusVO 返回结果
	 */
	private HouseStatusVO assembleHouseStatusVO(String statusCode, String statusName, Integer temCount) {
		HouseStatusVO houseStatusVO = new HouseStatusVO();
		houseStatusVO.setHouseStatusCode(statusCode);//状态value
		houseStatusVO.setStatusName(statusName);//状态名称
		houseStatusVO.setStatusCount(temCount);//状态数量
		return houseStatusVO;
	}

	private HouseVO assembleHouseVO(Object[] objects){
		HouseVO housevo = new HouseVO();
		housevo.setKeyword(((BigInteger)objects[0]).longValue());//房屋产品id
		housevo.setHouseNumber(objects[1]==null?"":(String)objects[1]);//产权房号
		return housevo;
	}

	/**
	 * 功能描述: 将一个住宅ＶＯ对象装配成一个住宅DO实体对象，对新增和修改进行不同处理
	 *
	 * @author 付湘辉
	 * Created on:2008-7-1
	 *
	 * 修改原因：
	 * @param flatVO
	 * @return FlatDomain 返回结果
	 */
	private FlatDomain assembleV2D(FlatVO flatVO) {
		FlatDomain flatDomain = this.wangleDomainInstance(flatVO);

		BeanUtil.convertVoAsDo(flatVO, flatDomain);

		BuildingDomain building = this.buildingDao.findById(flatVO.getBuildingId());
		flatDomain.setBuilding(building);//楼栋

		HousePlan housePlan = this.getHousePlanById(flatVO.getHousePlanId());
		flatDomain.setHousePlan(housePlan);//户型
		if (!BlankUtil.isBlank(housePlan)) {
			flatVO.setHousePlanName(housePlan.getName());
		}

		SysrefcodeDO deliveryLimitation = super.sysrefcodeDao.findById(flatVO.getDeliveryLimitationId());
		flatDomain.setDeliveryLimitation(deliveryLimitation);//交房标准
		if (!BlankUtil.isBlank(deliveryLimitation)) {
			flatVO.setDeliveryLimitationName(deliveryLimitation.getName());
		}

		// 检查必填字段
		flatDomain.checkRequiredField();
		// 检查面积规则
		flatDomain.checkHouseDimensionRole();

		HouseGrp houseGrp=this.buildingDao.getHouseGrpById(flatVO.getHouseGrpid());
		// 检查楼栋单元
		this.checkHouseGrp(houseGrp, building.getHasCell());
		flatDomain.setHouseGrp(houseGrp);//楼栋单元

		flatDomain.setDirection(flatVO.getDirectionId());//朝向,这里是一个id的字符串拼接，形式如：75,76,79

		//处理图片信息
		this.addOrEditIchnoAndPipeImage(flatVO, flatDomain);

		return flatDomain;
	}

	/**
	 * 功能描述: 将一个房屋数据数组对象装配成一个住宅房屋ＶＯ对象
	 *
	 * @author 付湘辉
	 * Created on:2008-7-8
	 *
	 * 修改原因：
	 * @param flatVoDataArray
	 * @return FlatVO 返回结果
	 */
	private FlatVO assemblevObjArray2FlatVO(Object[] flatVoDataArray) {
		FlatVO flatvo = new FlatVO();
		flatvo.setKeyword(((BigInteger)flatVoDataArray[0]).longValue());//房屋产品id
		flatvo.setFloor(((Short)flatVoDataArray[1]).intValue());//楼层
		flatvo.setCoalitionHouseId(flatVoDataArray[2]==null?null:((BigInteger)flatVoDataArray[2]).longValue());//管理房id
		flatvo.setCoalitionNumber(flatVoDataArray[3]==null?"":(String)flatVoDataArray[3]);//管理房号码
		flatvo.setHouseNumber(flatVoDataArray[4]==null?"":(String)flatVoDataArray[4]);//产权房号
		flatvo.setHousePlanName(flatVoDataArray[5]==null?"":(String)flatVoDataArray[5]);//产权房户型名称
		flatvo.setBuildSize(flatVoDataArray[6]==null?null:(BigDecimal)flatVoDataArray[6]);//建筑面积
		flatvo.setInnerSize(flatVoDataArray[7]==null?null:(BigDecimal)flatVoDataArray[7]);//套内面积
		flatvo.setStatusName(flatVoDataArray[8]==null?"":(String)flatVoDataArray[8]);//房屋状态
		flatvo.setRenovation(flatVoDataArray[9]==null?"":(String)flatVoDataArray[9]);//是否在装修中
		return flatvo;
	}

	/**
		 * 功能描述: 根据房屋图示对象数组装配一个HouseIconVO对象
		 *
		 * @author 付湘辉
		 * Created on:2008-7-7
		 *
		 * 修改原因：
		 * @param houseIconData
		 * @return HouseIconVO 返回结果
		 */
		private HouseIconVO assemblevObjArray2V(Object[] houseIconData) {
			HouseIconVO tempHouseIconVo = new HouseIconVO();
			tempHouseIconVo.setKeyword(((BigInteger)houseIconData[0]).longValue());//房屋产品id
			tempHouseIconVo.setCoalitionHouseId(houseIconData[2]==null?null:((BigInteger)houseIconData[2]).longValue());//管理房id
			tempHouseIconVo.setCoalitionNumber(houseIconData[3]==null?null:(String)houseIconData[3]);//管理房号码
			tempHouseIconVo.setHouseNumber(houseIconData[4]==null?"":(String)houseIconData[4]);//产权房号
			tempHouseIconVo.setHouseStatusCode((houseIconData[5]==null?"":(String)houseIconData[5]));//房屋状态value
			tempHouseIconVo.setRenovation(houseIconData[6]==null?"":(String)houseIconData[6]);//是否在装修中
			return tempHouseIconVo;
		}

	/**
	 * 功能描述:  检查房屋删除的业务规则  <br>
	 *
	 * @param flat
	 *
	 * Create author：付湘辉  <br>
	 * Create on:2008-7-25  <br>
	 * Edit author：  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private void checkHouseDeleteRole(FlatDomain flat) {
	    // 是不是未售的房屋
	    if (!SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_NOTONSALE.equals(flat.getStatus().getValue())) {
	        throw new BusinessException("house:house_not_notonsale_status_exception",BusinessException.WARNING);
	    }

	    // 是否已经登记了业主或其他住户
	    if (SysrefcodeDO.CONSTANTS_DIGITAL_ONE.equals(this.whetherRegistered(flat.getKeyword()))) {
	        throw new BusinessException("house:house_have_registration_owner_exception",BusinessException.WARNING);
	    }

	    //是否产生费用
	    if (this.hasChargeByHouse(flat)) {
	    	throw new BusinessException("house:house_have_produced_cost_exception",BusinessException.WARNING);
	    }

	    //走表
		List<MeterDomain> list = super.meterDao.getMeterListByHouseId(flat.getKeyword());
		if (!BlankUtil.isBlank(list)) {
			throw new BusinessException("house:house_have_produced_meter_exception",BusinessException.WARNING);
		}

	    // 如果已合并管理房
	    CoalitionHouseDomain coalHouse  = super.houseDao.getCoalition(flat);
	    if (!BlankUtil.isBlank(coalHouse)) {
	        Set<HouseDomain> set = coalHouse.getHouses();
	        if (!BlankUtil.isBlank(set)) {
	            for (HouseDomain domain : set) {
	                if (!domain.getKeyword().equals(flat.getKeyword())) {
	                    throw new BusinessException("house:house_have_merger_exception",BusinessException.WARNING);
	                }
	            }
	        }
	    }

	}

	/** 功能描述: 如果楼栋分单元并且传入的房屋中没有引用单元，则报异常 <br>
	 * @param houseGrp
	 * @param hasCell
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-5  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	*/
	private void checkHouseGrp(HouseGrp houseGrp, String hasCell) {
		if (SysrefcodeDO.CONSTANTS_DIGITAL_ONE.equals(hasCell)
				&& BlankUtil.isBlank(houseGrp)) {
			throw new BusinessException("house:house_housegrp_null_exception",BusinessException.WARNING);
		}
	}

	/** 功能描述:检查房号是否唯一  <br>
	 * @param flatvo 产权房VO
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-5  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	*/
	private void checkHouseNumberIsOnly(FlatVO flatvo) {
        super.checkParameterIsNull(flatvo.getHouseNumber(), "house:house_number_null_exception");
        flatvo.setHouseNumber(flatvo.getHouseNumber().toUpperCase());
		//在产权房和管理房中都检查此房号是否已存在
		if (this.checkIsOnlyHouseNoInHouseAndCoalitionHouse(flatvo.getProjectId(),flatvo.getKeyword(),flatvo.getHouseNumber())) {
			throw new BusinessException("house:house_number_exist_exception",BusinessException.WARNING);
		}
	}

	/**
	 * 功能描述: 根据房屋id查找所属楼栋，
	 * 如果houseId是管理房id，则找到其下任意一间产权房的所在楼栋 <br>
	 * @param houseId 房屋id
	 * @param isVirtual 是否是管理房，可为空；1管理房，0产权房
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-9-17  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private Long getBuildingIdByHouseId(Long houseId,String isVirtual){
		Long buildingId=null;
		if (SysrefcodeDO.CONSTANTS_DIGITAL_ONE.equals(isVirtual)) {
			CoalitionHouseDomain chouse = this.coalitionHouseDao.findById(houseId);
			Set<HouseDomain> set = chouse.getHouses();
			for (HouseDomain domain : set) {
				buildingId=domain.getBuilding().getKeyword();
				break;
			}
		}else{
			HouseDomain house = this.houseDao.findById(houseId);
			if (HibernateProxy.class.isInstance(house) ) {
				HibernateProxy  objProxy=(HibernateProxy)house;
				house = (HouseDomain)objProxy.getHibernateLazyInitializer().getImplementation();
			}
			if (CoalitionHouseDomain.class.isInstance(house)) {
				CoalitionHouseDomain chouse = (CoalitionHouseDomain)house;
				Set<HouseDomain> set = chouse.getHouses();
				for (HouseDomain domain : set) {
					buildingId=domain.getBuilding().getKeyword();
					break;
				}
			}else{
				buildingId = house.getBuilding().getKeyword();
			}
		}

		return buildingId;
	}

	/** 功能描述:  得到房屋平面图和管线图　<br>
	 * @param flatVO
	 * @param flatDO
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-14  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	*/
	private void getFlatImages(FlatVO flatVO, FlatDomain flatDO) {
		ImageDomain ichnography = flatDO.getIchnography();//平面图
		if (!BlankUtil.isBlank(ichnography))  {
			ImageVO image = this.assembleD2V(ichnography.getKeyword(), ichnography.getName(), ichnography.getPath(), null);
			flatVO.setIchnographyVo(image);
		}

		ImageDomain pipelineImage = flatDO.getPipelineImage();//管线图
		if (!BlankUtil.isBlank(pipelineImage))  {
			ImageVO image = this.assembleD2V(pipelineImage.getKeyword(), pipelineImage.getName(), pipelineImage.getPath(), null);
			flatVO.setPipelineVo(image);
		}
	}

	/**
	 * 功能描述: 根据房屋户型id查询户型DO实体对象
	 *
	 * @author 付湘辉
	 * Created on:2008-7-4
	 *
	 * 修改原因：
	 * @param housePlanId
	 * @return HousePlan 返回结果
	 */
	private HousePlan getHousePlanById(Long housePlanId){
		HousePlan housePlan = null;

		super.checkParameterIsNull(housePlanId, "common:parameters_null_exception, ");

		housePlan = this.houseDao.getHousePlanById(housePlanId);
		return housePlan;
	}

	/**
	 * 功能描述: 本地方法，判断房屋是否产生费用，应调用费用模块接口 <br>
	 * @param house
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-22  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private boolean hasChargeByHouse(HouseDomain house){
		ProRightDO proRight = this.proRightDao.getEffectiveProRightByHouse(house);
		if (BlankUtil.isBlank(proRight)) {
			return false;
		}
		AccountDomain account = this.accountDao.getAccountBy(proRight.getProRightId(), house.getKeyword(), true);
		if (BlankUtil.isBlank(account)) {
			return false;
		}
		Long count = this.transactionDao.getTransCountByAccount(account);

		return 0l == count ? false : true;
	}

    /**
	 * 功能描述: 如果房屋状态是"自住"、"空置"、"出租"这三种状态之一 ，返回true，否则返回false<br>
	 * @param value
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-25  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	private boolean isVSR(String value){
		return SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_RENTAL.equals(value)
				|| SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_VACANT.equals(value)
				|| SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_SINCETHELIVING.equals(value);
	}


    /**
	 * 功能描述: 将一个列表按参数得到其分页数据部分
	 *
	 * @author 付湘辉
	 * Created on:2008-6-2
	 *
	 * @param currentPage　当前页
	 * @param pageSize　页大小
	 * @param list　列表数据
	 * @return List<FloorVO>　分页列表
	 */
	private List<FloorVO> paginationList(Integer currentPage, Integer pageSize, List<FloorVO> list) {
		if (BlankUtil.isBlank(currentPage)) {
			currentPage = Integer.valueOf(1);
		}
		if (BlankUtil.isBlank(pageSize)) {
			pageSize = Integer.valueOf(9);
		}
		int totalCounts = list.size();

		if (totalCounts < 1) {
			return new ArrayList<FloorVO>();
		}
		int totalPages = (totalCounts + pageSize - 1) / pageSize ;

		currentPage = currentPage>totalPages?totalPages:currentPage<=0?1:currentPage;

		int fromIndex = Page.getStartOfPage(currentPage, pageSize);
		int toIndex = pageSize * currentPage;

		toIndex = toIndex > totalCounts?totalCounts:toIndex;

		List<FloorVO> resultList = list.subList(fromIndex, toIndex);

		return resultList;
	}
    
    /**
	 * 功能描述: 处理房屋朝向
	 *
	 * @author 付湘辉
	 * Created on:2008-7-4
	 *
	 * 修改原因：
	 * @param resultFlat
	 * @param directionIdStr
	 * @return void 返回结果
	 */
	private void processDirection(FlatVO resultFlat, String directionIdStr) {
		if (!BlankUtil.isBlank(directionIdStr)) {
			resultFlat.setDirectionId(directionIdStr);//朝向id字符串

			List<SysrefcodeDO> sysrefCodeList = super.sysrefcodeDao.querySysrefCodesBySelectId(SysrefcodeDO.CS_FLAT_WINDOW_FACE_CODE, directionIdStr);

			String [] directionNmaeStrArray = new String[sysrefCodeList.size()];
			int i = 0;
			for (SysrefcodeDO sysrefcodeDO : sysrefCodeList) {
				directionNmaeStrArray[i++] = sysrefcodeDO.getName();
			}

			resultFlat.setDirectionName(StringAnalysiUtil.portfolioFormattedString(directionNmaeStrArray));//朝向名称字符串
		}
	}

	/** 功能描述:  <br>
	 * @param flatvo
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-14  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	*/
	private void processIfProduceException(FlatVO flatvo) {
		if (!BlankUtil.isBlank(flatvo.getIchnographyVo())) {
			UpLoadFile.deleteFile(flatvo.getIchnographyVo());
		}

		if (!BlankUtil.isBlank(flatvo.getPipelineVo())) {
			UpLoadFile.deleteFile(flatvo.getPipelineVo());
		}
	}

	/**
	 * 功能描述: 处理房间数不够最大数量的情况　　
	 *
	 * @author 付湘辉
	 * Created on:2008-7-7
	 *
	 * 修改原因：
	 * @param tmpMaxHouseCount
	 * @param resultList
	 * @return void 返回结果
	 */
	private void processInsufficientNumber(Integer tmpMaxHouseCount, List<FloorVO> resultList) {
		HouseIconVO tempHouseIconVo;
		for (FloorVO tempFloor : resultList) {
			int houseCount = tempFloor.getHouseIconList().size();
			//当房间数不足最大数时，用一个初始化的空VO对象补充
			while(houseCount < tmpMaxHouseCount){
				tempHouseIconVo = new HouseIconVO();
				tempFloor.getHouseIconList().add(houseCount++, tempHouseIconVo);
			}
		}
	}

	/** 功能描述:  <br>
	 * @param flatVO
	 * @return
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-5  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	*/
	private FlatDomain wangleDomainInstance(FlatVO flatVO) {
		FlatDomain flatDomain=null;
		SysInfo sysInfo=null;
		if (BlankUtil.isBlank(flatVO.getKeyword())) {
			flatDomain= new FlatDomain();
			sysInfo = super.createInfo(flatVO.getCreator());
			flatDomain.setSysInfo(sysInfo);//创建者和修改者信息

			SysrefcodeDO status =
				super.sysrefcodeDao.getSysrefCodesByCode(SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_CODE, SysrefcodeDO.HM_HOUSE_HOUSE_STATUS_VALUE_NOTONSALE);
			flatDomain.setStatus(status);//房屋状态，新建时为未售
		}else{
			flatDomain=(FlatDomain)this.flatDao.findById(flatVO.getKeyword());
            sysInfo = flatDomain.getSysInfo();
			super.modifyInfo(sysInfo, flatVO.getCreator());
		}
		return flatDomain;
	}

	/**
     * 功能描述:  是否已经登记了业主或其他住户信息  <br>
     *
     * @param houseId
     *
     * Create author：付湘辉  <br>
     * Create on:2008-7-25  <br>
     * Edit author：  <br>
     * Edit on:    <br>
     * Why:     <br>
     */
    private String whetherRegistered(Long houseId) {
        List list = super.clientRHouseDao.getClientRHouseListByHouseId(houseId);
        if (BlankUtil.isBlank(list)) {
            return SysrefcodeDO.CONSTANTS_DIGITAL_ZERO;
        }
        return SysrefcodeDO.CONSTANTS_DIGITAL_ONE;
    }

}
